package com.example.riceexambackend.service.impl;

import com.example.riceexambackend.common.errorcode.ServiceErrorCodeConstants;
import com.example.riceexambackend.common.exception.ServiceException;
import com.example.riceexambackend.common.utils.EncryptUtil;
import com.example.riceexambackend.common.utils.JWTUtil;
import com.example.riceexambackend.common.utils.RegexUtil;
import com.example.riceexambackend.controller.param.user.UserCurrentParam;
import com.example.riceexambackend.controller.param.user.UserLoginPasswordParam;
import com.example.riceexambackend.controller.param.user.UserRegisterParam;
import com.example.riceexambackend.dao.dataobject.UserDO;
import com.example.riceexambackend.dao.mapper.UserMapper;
import com.example.riceexambackend.service.UserService;
import com.example.riceexambackend.service.VerificationCodeService;
import com.example.riceexambackend.service.dto.user.UserCurrentDTO;
import com.example.riceexambackend.service.dto.user.UserLoginDTO;
import com.example.riceexambackend.service.dto.user.UserRegisterDTO;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private VerificationCodeService verificationCodeService;

//    @Override
//    public UserLoginDTO login(UserLoginBaseParam param) {
//        if (param instanceof UserLoginVerifyCodeParam codeParam) {
//            // 验证码登录
//            return loginByCode(codeParam);
//        } else if (param instanceof UserLoginPasswordParam pwdParam) {
//            // 密码登录
//            return loginByPassword(pwdParam);
//        } else {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_NOT_EXISTS);
//        }
//    }
//
    /**
     * 根据密码进行登录
     * @param pwdParam 密码登录参数
     * @return DTO对象
     */
    public UserLoginDTO loginByPassword(UserLoginPasswordParam pwdParam) {
        // 1. 校验参数
        if (pwdParam == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PARAM_NULL);
        }
        // 2. 校验用户账号
        String userAccount = pwdParam.getUserAccount();
        if (!RegexUtil.checkUserAccount(userAccount)) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_ACCOUNT_ERROR);
        }
        // 3. 校验用户密码
        String userPwd = pwdParam.getUserPwd();
        if (!RegexUtil.checkPassword(userPwd)) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PWD_ERROR);
        }
        // 4. 从数据库中根据账号查询用户
        UserDO dbUser = userMapper.selectByAccount(userAccount);
        if (dbUser == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_NOT_EXISTS);
        }
        // 5. 比对密码
        if (!dbUser.getUserPwd().equals(
                EncryptUtil.encryptBySha256(userPwd)
        )) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PWD_ERROR);
        }
        // 5. 封装DTO返回对象
        Map<String, Object> claim = new HashMap<>();
        claim.put("id", dbUser.getId());
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        userLoginDTO.setToken(JWTUtil.genToken(claim));
        userLoginDTO.setUserRole(dbUser.getUserRole());
        return userLoginDTO;
    }
//
//    /**
//     * 根据验证码进行登录
//     * @param codeParam 验证码登录参数
//     * @return DTO对象
//     */
//    private UserLoginDTO loginByCode(UserLoginVerifyCodeParam codeParam) {
//        // 1. 校验参数
//        if (codeParam == null) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PARAM_NULL);
//        }
//        // 2. 校验手机号码格式
//        if (!RegexUtil.checkMobile(codeParam.getPhoneNumber())) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PHONE_ERROR);
//        }
//        // 3. 校验用户身份信息
//        UserDO dbUser = userMapper.selectByPhoneNumber(new PhoneNumberEncrypt(codeParam.getPhoneNumber()));
//        if (dbUser == null) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_NOT_EXISTS);
//        }
//        if (StringUtils.hasText(codeParam.getMandatory())
//                && !codeParam.getMandatory()
//                    .equalsIgnoreCase(dbUser.getIdentity())) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_IDENTITY_ERROR);
//        }
//        // 4. 校验用户验证码
//        String code = verificationCodeService.getVerifyCode(codeParam.getPhoneNumber());
//        if (!StringUtils.hasText(codeParam.getCaptchaCode())
//                || !codeParam.getCaptchaCode().equals(code)) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_CODE_ERROR);
//        }
//        // 5. 封装DTO返回对象
//        UserLoginDTO userLoginDTO = new UserLoginDTO();
//        Map<String, Object> claim = new HashMap<>();
//        claim.put("id", dbUser.getId());
//        userLoginDTO.setToken(JWTUtil.genToken(claim));
//        userLoginDTO.setIdentity(dbUser.getIdentity());
//        return userLoginDTO;
//    }

    @Override
    public UserRegisterDTO register(UserRegisterParam param) {
        // 校验用户身份信息
        checkUserInfo(param);
        // 用户密码、邮箱加密存库
        UserDO userDO = new UserDO();
        userDO.setUserAccount(param.getUserAccount());
        userDO.setUserPwd(EncryptUtil.encryptBySha256(param.getUserPwd()));
        userMapper.insertUser(userDO);
        // 返回dto对象
        UserRegisterDTO dto = new UserRegisterDTO();
        dto.setId(userDO.getId());
        return dto;
    }

    @Override
    public UserCurrentDTO getCurrentUser(UserCurrentParam param) {
        // 1. 校验参数
        if (param == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_CURRENT_PARAMS_NULL);
        }
        // 2. 解析token
        String token = param.getToken();
        Claims claims = JWTUtil.parseJWT(token);
        if (claims == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_CURRENT_ERROR);
        }
        // 3. 从载荷中获取用户id
        long userId = (int) claims.get("id");
        // 4. 查询数据库记录
        UserDO dbUser = userMapper.selectById(userId);
        if (dbUser == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_CURRENT_ERROR);
        }
        // 5. 返回登录用户信息
        UserCurrentDTO userCurrentDTO = new UserCurrentDTO();
        userCurrentDTO.setUserName(dbUser.getUserName());
        userCurrentDTO.setUserEmail(dbUser.getUserEmail());
        userCurrentDTO.setUserPhone(dbUser.getUserPhone());
        userCurrentDTO.setUserRole(dbUser.getUserRole());
        userCurrentDTO.setUserAccount(dbUser.getUserAccount());
        return userCurrentDTO;
    }

    /**
     * 校验用户基本信息
     * @param param 用户注册参数
     */
    private void checkUserInfo(UserRegisterParam param) {
        // 0. 校验用户参数
        if (param == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_REG_PARAM_NULL);
        }
        // 1. 校验用户账号
        String userAccount = param.getUserAccount();
        if (!RegexUtil.checkUserAccount(userAccount)) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_REG_ACCOUNT_ERROR);
        }
        // 2. 校验用户密码信息
        String userPwd = param.getUserPwd();
        if (!RegexUtil.checkPassword(userPwd)) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_REG_PWD_ERROR);
        }
        // 3. 校验用户账号是否已存在
        if (userMapper.countByAccount(userAccount) > 0) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_REG_ACCOUNT_EXISTS);
        }
    }
}
